class UserGroup < ActiveRecord::Base
  has_and_belongs_to_many :permissions
  has_and_belongs_to_many :users

  validates_presence_of :name
  
  class << self
    #
    # Pull from the Lockdown::UserGroups module if not found in the database.
    # Otherwise, database data trumps Lockdown::UserGroups as the group may
    # have been redefined in the database.
    #
    # Always pull from the Lockdown::UserGroups module if in testing mode.
    #
    def [](sym)
			if Lockdown::UserGroups.protected_records.include?(sym)
				return Lockdown::UserGroups[sym] 
			end

      unless ENV['RAILS_ENV'] == "test"
        ug = UserGroup.find_by_name(sym.to_title_str)
      end
      if ug.nil?
        Lockdown::UserGroups[sym]
      else
        ug.permissions
      end
    end
    
    def find_by_sym(sym)
      if ENV['RAILS_ENV'] == "test"
        new(:name => sym.to_title_str)
      else
        find_by_name(sym.to_title_str)
      end
    end
    
		#
    # Use this in your migrations to create a db record for management
    # functionality.  
    #
    def create_record(sym)
      raise NameError.new("#{sym} is not defined.") unless Lockdown::UserGroups.respond_to?(sym)
      ug = create(:name => sym.to_title_str)
      unless Lockdown::UserGroups.protected_records.include?(sym)
        Lockdown::UserGroups[sym].each do |sobj|
          ug.system_objects << Permission.find_or_create_by_name(sobj.to_title_str)
        end
      end
      ug.save
    end

    #
    # Use this in your migrations to add permissions to a user group 
    # identified by sym.
    #
    # perms are param(s) of symbols
    # e.g. add_permission(:public_access, :view_catalog)
    #
    def add_permissions(sym, *perms)
     ug = find_by_sym(sym)
     raise NameError.new("#{sym} is not defined.") if ug.nil?
     perms.each do |perm|
          ug.permissions << Permission.find_or_create_by_name(perm.to_title_str)
     end
    end
    
    #
    # Use this in your migrations to remove permissions from a user group 
    # identified by sym.
    #
    # perms are param(s) of symbols
    # e.g. add_permissionss(:catalog_management, :manage_categories,
    #                     :manage_products)
    #
    def remove_permissions(sym, *perms)
     ug = find_by_sym(sym)
     raise NameError.new("#{sym} is not defined.") if ug.nil?
     perms.each do |perm|
          ug.permissions.delete Permission.find_by_name(perm.to_title_str)
     end
    end
    
    #
    # Use this in your migrations to delete the user group identified by sym.
    #
    def delete_record(sym)
      ug = find_by_sym(sym)
      ug.destroy unless ug.nil?
    end
    
  end # end class block
  
  #
  # Return an array of the permissions for the UserGroup object
  #
  def all_permissions
    if permissions.empty?
      sym = self.name.to_title_sym
      Lockdown::UserGroups[sym]
    else
      methods_from_database
    end
  rescue Exception => e
    []
  end
  
  eprivate
    def methods_from_database
      Lockdown::Permissions.methods_from  permissions.to_syms_from_names
    end
end
